home *** CD-ROM | disk | FTP | other *** search
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
-
- #import "WWSceneClock.h"
- #import "WW3DWell.h" // for delegate routine
- #import "WWEveParser.h" // for setTicksPerSecond
-
- @implementation WWSceneClock
-
- + initialize { return [WWSceneClock setVersion:2], self; }
-
- - init
- {
- [super init];
-
- currentTime = 0.0;
- samplesPerSecond = 60.0;
- increment = 1./samplesPerSecond;
- skip = 10. * increment;
- timedEntry = (DPSTimedEntry)0;
- ratio = 1.;
- isPaused = YES;
- mark = 3.0;
-
- return self;
- }
-
- - awake
- {
- [super awake];
- timedEntry = (DPSTimedEntry)0;
- isPaused = YES;
- return self;
- }
-
- - (BOOL)isPaused { return isPaused; }
-
- - removeTimedEntry
- {
- if (timedEntry)
- { DPSRemoveTimedEntry(timedEntry);
- timedEntry = (DPSTimedEntry)0;
- isPaused = YES;
- }
- isPaused = YES;
- return self;
- }
-
- - free
- {
- [self removeTimedEntry];
- return [super free];
- }
-
- - reset:sender
- {
- [self removeTimedEntry];
- currentTime = 0.0;
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - (float)mark { return mark; }
-
- - setMark:(float)newMark
- { mark = newMark;
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - takeMark:sender
- {
- [self setMark:[sender floatValue]];
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// increment /////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)increment { return increment; }
-
- - increment:sender
- {
- [self removeTimedEntry];
- currentTime += increment;
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - setIncrement:(float)newIncrement
- {
- if (newIncrement <= 0.0)
- { NXLogError("sceneClockIncrement must be > 0.\n");
- return nil;
- }
- increment = newIncrement;
- // need to tell the model's interp about the value of samplesPerSecond
- // set the increment appropriately...
- samplesPerSecond = 1.0/increment;
- [scene setTicksPerSecond:samplesPerSecond];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// skip /////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)skip { return skip; }
-
- - skip:sender
- {
- [self removeTimedEntry];
- currentTime += skip;
- return self;
- }
-
- - setSkip:(float)newSkip
- {
- if (newSkip <= 0.0)
- { NXLogError("sceneClockSkip must be > 0.\n");
- return nil;
- }
- skip = newSkip;
- // need to tell the model's interp about the value of samplesPerSecond
- // set the skip appropriately...
- [delegate revertSceneClockInspector];
- return self;
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// current time //////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)timestamp { return currentTime; }
- - setCurrentTime:(float)newTime
- {
- if (newTime < 0.0)
- { NXLogError("negative time is not valid in WavesWorld.\n");
- return nil;
- }
- [self removeTimedEntry];
- currentTime = newTime;
- [delegate revertSceneClockInspector];
- return self;
- }
-
-
- - decrement:sender
- {
- [self removeTimedEntry];
- currentTime -= increment;
- if (currentTime < 0.0)
- { currentTime = 0.0;
- }
- [delegate revertSceneClockInspector];
- return self;
- }
-
- static void fastForwardFunc(DPSTimedEntry tag, double now, char *userdata)
- {
- WWSceneClock *self = (id)userdata;
-
- self->currentTime += self->skip;
- if (self->currentTime > self->mark)
- { // I'm at the stop mark; so stop
- [self->delegate pause:nil];
- }
- // should probably send a msg to a delegate to tell it that the scene info has changed...
- [self->delegate revertSceneClockInspector];
-
- return ;
- }
-
- - fastForward:sender
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(increment * ratio),
- (DPSTimedEntryProc)fastForwardFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- isPaused = NO;
- return self;
- }
-
- static void rewindFunc(DPSTimedEntry tag, double now, char *userdata)
- {
- WWSceneClock *self = (id)userdata;
-
- self->currentTime -= self->skip;
- if (self->currentTime < 0.0)
- { self->currentTime = 0.0;
- // I'm totally rewound, stop
- [self->delegate pause:nil];
- }
- // should probably send a msg to a delegate to tell it that the scene info has changed...
- [self->delegate revertSceneClockInspector];
-
- return ;
- }
-
- - rewind:sender
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(increment * ratio),
- (DPSTimedEntryProc)rewindFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- isPaused = NO;
- return self;
- }
-
- - pause:sender
- {
- [self removeTimedEntry];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- static void playFunc(DPSTimedEntry tag, double now, char *userdata)
- {
- WWSceneClock *self = (id)userdata;
-
- if (!self->waiting) // great! we can increment!
- { self->currentTime += self->increment;
- }
- else
- { if (
-
- }
- if (self->currentTime > self->mark)
- { // I'm at the stop mark; so stop
- [self->delegate pause:nil];
- }
- else
- { // restart stuff
- [self installHighFrequencyCheck]; // back to initial mode
- }
-
- // should probably send a msg to a delegate to tell it that the scene info has changed...
- [self->delegate revertSceneClockInspector];
-
- return ;
- }
-
- - installLowFrequencyCheck
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(lowFrequency * increment * ratio),
- (DPSTimedEntryProc)playFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- startTime = ; // get current wall time
- dropDeadTime = startTime + (increment * ratio);
- count = 0;
- waiting = YES;
- isPaused = NO;
- return self;
- }
-
- - installHighFrequencyCheck
- {
- [self removeTimedEntry];
- timedEntry = DPSAddTimedEntry((double)(highFrequency * increment * ratio),
- (DPSTimedEntryProc)playFunc,
- self,
- NX_MODALRESPTHRESHOLD);
- count = 0;
- waiting = YES;
- isPaused = NO;
- return self;
- }
-
- - play:sender
- {
- return [self installHighFrequencyCheck];
- }
-
- /////////////////////////////////////////////////////////////////////////
- ///////////////////////// samples/sec //////////////////////////////////
- /////////////////////////////////////////////////////////////////////////
- - (float)samplesPerSecond { return samplesPerSecond; }
-
- - setSamplesPerSecond:(float)newRate
- {
- if (newRate < 0.0)
- { NXLogError("scene sample rate must be positive, not %d\n", newRate);
- return nil;
- }
- [self removeTimedEntry];
- samplesPerSecond = newRate;
- increment = 1.0/samplesPerSecond;
- skip = 10. * increment;
- [scene setTicksPerSecond:samplesPerSecond];
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - (float)ratio { return ratio; }
-
- - setRatio:(float)newRatio
- {
- if (newRatio < 0.0)
- { NXLogError("the ratio of real time to scene time must be positive, not %d\n", newRatio);
- return nil;
- }
- [self removeTimedEntry];
- ratio = newRatio;
- [delegate revertSceneClockInspector];
- return self;
- }
-
- - setDelegate:newDelegate { delegate = newDelegate; return self; }
- - setScene:newScene { scene = newScene; return self; }
-
- // NeXTSTEP archiving:
-
- #define typeVectorVersion1 "fffff"
- #define typeValuesVersion1 ¤tTime, &increment, &skip, &samplesPerSecond, &ratio
-
- #define typeVector "ffffff"
- #define typeValues ¤tTime, &increment, &skip, &samplesPerSecond, &ratio, &mark
-
- - read:(NXTypedStream*)stream
- {
- int version;
-
-
- [super read:stream];
-
- version = NXTypedStreamClassVersion(stream,"WWSceneClock");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1)
- { NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
- scene = NXReadObject(stream);
- delegate = NXReadObject(stream);
- mark = 3.0;
- }
- if (version == 2)
- { NXReadTypes(stream, typeVector, typeValues);
- scene = NXReadObject(stream);
- delegate = NXReadObject(stream);
- }
-
- return self;
- }
-
- - write:(NXTypedStream*)stream
- {
- [super write:stream];
-
- NXWriteTypes(stream,typeVector, typeValues);
- NXWriteObjectReference(stream, scene);
- NXWriteObjectReference(stream, delegate);
-
- return self;
- }
-
-
- @end
-